﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OOPA_opdracht.Model
{
    public class Node
    {
        protected Inputs firstInput = Inputs.NO_INPUT;
        private Inputs secondInput = Inputs.NO_INPUT;
        private Inputs output = Inputs.NO_INPUT;
        private Nodes.Nodes node;
        private List<Node> nextNodes;
        private string name;

        public Node()
        {
            firstInput = 0;
            nextNodes = new List<Node>();
        }

        public Node(string name)
        {
            this.name = name;
            nextNodes = new List<Node>();
        }

        public Node(Nodes.Nodes node, string name)
        {
            this.name = name;
            this.node = node;
            nextNodes = new List<Node>();
        }

        public void setFirstNumber(Inputs firstNumber)
        {
            this.firstInput = firstNumber;
        }

        /// <summary>
        /// Recursively counts each node their output
        /// </summary>
        public void setNextNodesTheirNumbers()
        {
            if (nextNodes.Count() == 0)
            {
                print();
            }
            

            if (output != Inputs.NO_INPUT)
            {
                foreach (Node n in nextNodes)
                {
                    if (n.firstInput == Inputs.NO_INPUT)
                        setFirstInput(output, n);
                    else
                        n.secondInput = output;
                    n.count();
                }
                
            }
        }

        public virtual void setFirstInput(Inputs firstInput, Node nextNode)
        {
            //print();
            nextNode.firstInput = firstInput;
        }

        public virtual void print() 
        {
            Console.WriteLine("This is " + name + "'s output: " + firstInput);
        }

        public void setOutput(Inputs output)
        {
            this.output = output;
        }

        public void addNextNode(Node node)
        {
            if (!nextNodes.Contains(node) && node != null)
                nextNodes.Add(node);
            else
                Console.WriteLine("Node already exists in Next Nodes...");
        }

        public void deleteNextNode(Node node) 
        { 
            nextNodes.Remove(node); 
        }

        public void count()
        {
            switch (node)
            {
                case Nodes.Nodes.NOT:
                    output = NodeNOT.singleOperatorNode(firstInput);
                    break;
                case Nodes.Nodes.AND:
                    output = NodeAND.doubleOperatorNode(firstInput, secondInput);
                    break;
                case Nodes.Nodes.NAND:
                    output = NodeNAND.doubleOperatorNode(firstInput, secondInput);
                    break;
                case Nodes.Nodes.NEGAND:
                    output = NodeNegativeAND.doubleOperatorNode(firstInput, secondInput);
                    break;
                case Nodes.Nodes.NEGOR:
                    output = NodeNegativeOR.doubleOperatorNode(firstInput, secondInput);
                    break;
                case Nodes.Nodes.NOR:
                    output = NodeNOR.doubleOperatorNode(firstInput, secondInput);
                    break;
                case Nodes.Nodes.OR:
                    output = NodeOR.doubleOperatorNode(firstInput, secondInput);
                    break;
                case Nodes.Nodes.XNOR:
                    output = NodeXNOR.doubleOperatorNode(firstInput, secondInput);
                    break;
                case Nodes.Nodes.XOR:
                    output = NodeXOR.doubleOperatorNode(firstInput, secondInput);
                    break;
                default:
                    output = Inputs.NO_INPUT;
                    break;                
            }
            setNextNodesTheirNumbers();
        }
    }
}
